const fs = require('fs');
const path = require('path');
const XLSX = require('xlsx');

/**
 * 递归获取目录结构，仅添加无子目录的目录和文件
 * @param {string} dirPath - 目标目录路径
 * @param {string} parentPath - 父目录路径
 * @param {Array} result - 存储结果的数组
 * @returns {Array} 目录结构数组
 */
function getDirectoryStructure(dirPath, parentPath = '', result = []) {
  try {
    const files = fs.readdirSync(dirPath);
    
    files.forEach(file => {
      const fullPath = path.join(dirPath, file);
      const relativePath = parentPath ? path.join(parentPath, file) : file;
      const stats = fs.statSync(fullPath);
      
      if (stats.isDirectory()) {
        // 检查子目录数量
        const subFiles = fs.readdirSync(fullPath);
        
        // 只有当目录没有子目录时才添加
        if (subFiles.length === 0) {
          result.push({ path: relativePath, type: 'directory' });
        } else {
          // 有子目录时不添加当前目录，但递归处理子目录
          getDirectoryStructure(fullPath, relativePath, result);
        }
      } else {
        // 文件直接添加
        result.push({ path: relativePath, type: 'file' });
      }
    });
  } catch (error) {
    console.warn(`read file Error: ${dirPath}`, error);
  }
  
  return result;
}

/**
 * 将目录结构转换为Excel数据并获取合并区域
 * @param {Array} structure - 目录结构数组
 * @returns {Object} 包含Excel数据和合并区域的对象
 */
function structureToExcelWithMerges(structure) {
  // 确定最大路径层级数
  const maxDepth = structure.reduce((max, item) => {
    const depth = item.path.split(path.sep).length;
    return depth > max ? depth : max;
  }, 0);
  
  // 初始化Excel数据（第一行为表头）
  const excelData = [[]];
  for (let i = 1; i <= maxDepth; i++) {
    excelData[0].push(`层级${i}`); // 设置层级表头
  }
  
  // 填充路径数据
  structure.forEach(item => {
    const pathParts = item.path.split(path.sep);
    const row = [];
    for (let i = 0; i < maxDepth; i++) {
      row[i] = pathParts[i] || '';
    }
    excelData.push(row);
  });
  
  // 生成合并区域
  const mergeRegions = [];
  for (let col = 0; col < maxDepth; col++) {
    let currentValue = null;
    let startRow = -1; // 数据行从1开始（excelData[0]是表头）
    
    for (let row = 1; row < excelData.length; row++) {
      const value = excelData[row][col] || '';
      
      if (startRow === -1) {
        currentValue = value;
        startRow = row;
        continue;
      }
      
      if (value === currentValue) {
        continue; // 继续当前合并区域
      } else {
        // 结束当前合并区域
        if (startRow < row - 1) {
          mergeRegions.push({
            s: { r: startRow, c: col },    // 起始行/列（0索引）
            e: { r: row - 1, c: col }     // 结束行/列（0索引）
          });
        }
        currentValue = value;
        startRow = row;
      }
    }
    
    // 处理最后一个合并区域
    if (startRow < excelData.length - 1) {
      mergeRegions.push({
        s: { r: startRow, c: col },
        e: { r: excelData.length - 1, c: col }
      });
    }
  }
  
  return { excelData, mergeRegions, maxDepth };
}

/**
 * 生成带合并单元格的目录结构Excel
 * @param {string} dirPath - 目标目录路径
 * @param {string} outputPath - 输出Excel路径
 * @returns {Promise} 处理Promise
 */
function generateDirectoryExcel(dirPath, outputPath) {
  return new Promise((resolve, reject) => {
    try {
      if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) {
        reject(new Error(`目录不存在: ${dirPath}`));
        return;
      }
      
      const structure = getDirectoryStructure(dirPath);
      const { excelData, mergeRegions, maxDepth } = structureToExcelWithMerges(structure);
      
      const workbook = XLSX.utils.book_new();
      const worksheet = XLSX.utils.aoa_to_sheet(excelData);
      
      // 应用合并区域
      if (mergeRegions.length > 0) {
        worksheet['!merges'] = mergeRegions;
      }
      
      XLSX.utils.book_append_sheet(workbook, worksheet, '目录结构');
      XLSX.writeFile(workbook, outputPath);
      
      resolve({
        message: `已生成带合并单元格的目录结构Excel`,
        fileCount: structure.length,
        mergeCount: mergeRegions.length
      });
    } catch (error) {
      reject(error);
    }
  });
}

// 使用示例
// const targetDir = 'E:\\项目\\test';      // 替换为目标目录
const targetDir = 'D:\\testAutoMoveFile';      // 替换为目标目录
const outputExcel = './directory-merged.xlsx'; // 替换为输出路径

generateDirectoryExcel(targetDir, outputExcel)
  .then(result => {
    console.log(result.message);
    console.log(`file count: ${result.fileCount}`);
    console.log(`change num: ${result.mergeCount}`);
  })
  .catch(error => {
    console.error('File Add Error:', error);
  });